﻿/************************************************************************

 This file is part of "10 Second Tim".

 "10 Second Tim" is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 "10 Second Tim" is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with "10 Second Tim".  If not, see <http://www.gnu.org/licenses/>.

************************************************************************/

// All code (c)2013 Scott Bevin. all rights reserved

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LDE;
using LDE.Input;
using LudumDare27.Games.Game_1;
using LudumDare27.GameScreens;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace LudumDare27.Games.Game_5
{
	public class GameplayScreen : GameScreen
	{
		public static bool PlayedYet = false;
		private Camera m_cam;
		private SpriteFont levelInfoFont;

		public Character m_playerchar = null;

		private InputTrigger m_jumpInput = new InputTrigger( "Jump" );

		private WhiteFadeScreen whiteFadeScreen = null;

		private ScreenBorder border;

		private float levelTimer = 0.0f;
		private float deadTimer = 0.0f;
		public int Level;
		private float camExtrarot = 0.0f;

		private RocketTerrain terrain;

		private SoundEffect whiteNoiseSfx;
		private SoundEffectInstance whiteNoiseSfxInstance;
		private SoundEffect newLevelSfx;

		private SoundEffect rocketSfx;
		private SoundEffectInstance rocketSfxInstance;

		public GameplayScreen( int level )
			: base( true )
		{
			Level = level;
		}

		private Song backgroundMusic;

		override public void OnAdded( )
		{
			backgroundMusic = ( (LD27Game)Game ).PickSong( ContentManager );
			MediaPlayer.Play( backgroundMusic );
			MediaPlayer.IsRepeating = true;
			whiteNoiseSfx = ContentManager.Load<SoundEffect>( "Sfx/AboutToTrans" );
			whiteNoiseSfxInstance = whiteNoiseSfx.CreateInstance( );
			whiteNoiseSfxInstance.IsLooped = true;
			whiteNoiseSfxInstance.Play( );

			rocketSfx = ContentManager.Load<SoundEffect>( "Sfx/Rockets" );
			rocketSfxInstance = rocketSfx.CreateInstance( );
			rocketSfxInstance.IsLooped = true;
			rocketSfxInstance.Play( );

			newLevelSfx = ContentManager.Load<SoundEffect>( "Sfx/NewLevel" );
			newLevelSfx.Play( );
			border = new ScreenBorder( ContentManager );
			levelInfoFont = ContentManager.Load<SpriteFont>( "Fonts/DebugFont" );
			Random rnd = new Random( );

			m_cam = new Camera( Game.GraphicsDevice.PresentationParameters.BackBufferWidth,
				Game.GraphicsDevice.PresentationParameters.BackBufferHeight );
			m_cam.Zoom = 0.5f;

			float rotDir = (float)( rnd.NextDouble( ) * 2.0f ) - 1.0f;
			m_cam.Rotation = m_cam.TargetRotation = (float)( Math.PI * 2.0f * rotDir * ( 0.1f * Level ) );
			m_cam.Zoom += (float)rnd.NextDouble( ) * 0.5f;

			m_playerchar = new Character( ContentManager.Load<Texture2D>( "Img/Chars/GarryRocket" ), ContentManager );
			m_playerchar.CurrentAnim = new WalkAnim( 0.5f, false );
			m_playerchar.Velocity.X = Defs.Game5.BaseMoveSpeed;

			int tilesNeeded = (int)( ( ( m_playerchar.Velocity.X / Defs.Game5.TileWidth ) * 10.0f ) + 20 );
			terrain = new RocketTerrain( this, tilesNeeded, Defs.Game5.TileWidth );

			// provide constant grav

			m_cam.Position = m_cam.TargetPosition = m_playerchar.Position;

			m_jumpInput.Add( Buttons.A ).Add( Keys.W ).Add( Keys.Up ).Add( Keys.Space ).Add( Keys.Enter );

			// 			if ( Level > 5 )
			// 				camExtrarot = ( (float)rnd.NextDouble( ) * 2.0f ) - 1.0f * ( (float)Math.PI * 0.01f * ( Level ) );
			//
			// 			if ( rnd.Next( 100 ) < 50 )
			// 				camExtrarot = -camExtrarot;

			if ( !PlayedYet )
			{
				m_cam.Rotation = m_cam.TargetRotation = 0.0f;
				m_cam.Zoom = Defs.Zoom;
				camExtrarot = 0.0f;
			}
			base.OnAdded( );
		}

		override public void Update( float dt )
		{
			if ( m_playerchar.Dead )
				levelTimer = 0.0f;

			levelTimer += dt;

			InputHandler input = Player.Get.GetInput( this );
			whiteNoiseSfxInstance.Volume = 0.0f;
			if ( levelTimer > 3.0f )
			{
				whiteNoiseSfxInstance.Volume = MathHelper.Clamp( 1.0f - ( ( 10.0f - levelTimer ) / 3.0f ), 0.0f, 1.0f );
			}
			if ( levelTimer < 9.5f )
			{
				if ( input != null && !m_playerchar.Dead )
				{
					m_playerchar.Acceleration.Y = Defs.Game5.Gravity;
					rocketSfxInstance.Volume = 0.25f;
					if ( input.IsHeld( m_jumpInput ) != null )
					{
						m_playerchar.Acceleration.Y = -Defs.Game5.Gravity * 2.0f;
						rocketSfxInstance.Volume = 1.0f;
					}
				}

				m_playerchar.OnGround = false;
				m_playerchar.Update( dt, 0.0f, true );

				if ( !m_playerchar.Dead )
				{
					m_cam.TargetPosition = m_playerchar.Position;

					m_cam.Rotation += camExtrarot * dt;
					m_cam.TargetRotation = m_cam.Rotation;
				}

				m_cam.Update( dt );

				if ( !m_playerchar.Dead )
				{
					RocketTerrain.Tile tile = terrain.GetTileAtPos( m_playerchar.Position.X );

					float ty = ( tile.Pos.Y - tile.HeightDiv2 );
					float by = ( tile.Pos.Y + tile.HeightDiv2 );

					if ( m_playerchar.Position.Y - m_playerchar.m_sprite.origin.Y < ty || m_playerchar.Position.Y + m_playerchar.m_sprite.origin.Y > by )
					{
#if SILVERLIGHT
			rocketSfxInstance.Stop(  );
#else
						rocketSfxInstance.Stop( true );
#endif
						m_playerchar.Kill( );
						m_playerchar.Velocity = m_playerchar.Acceleration = Vector2.Zero;
						m_playerchar.Velocity.Y = -360.0f;
						m_playerchar.Acceleration.Y = Defs.Game5.Gravity;
						deadTimer = 0.0f;
					}
				}
				else
				{
					if ( ( deadTimer += dt ) >= 2.0f )
					{
						if ( whiteFadeScreen == null )
						{
							whiteFadeScreen = new WhiteFadeScreen( );
							GameScreenManager.AddGameScreen( whiteFadeScreen, null, GameScreenManager.AddGameScreenData.PositioningOptions.OnTop );
						}
					}
				}
			}
			else
			{
				if ( whiteFadeScreen == null )
				{
					whiteFadeScreen = new WhiteFadeScreen( );
					GameScreenManager.AddGameScreen( whiteFadeScreen, null, GameScreenManager.AddGameScreenData.PositioningOptions.OnTop );
				}
			}

			if ( whiteFadeScreen != null && whiteFadeScreen.State == WhiteFadeScreen.States.FadedIn )
			{
				whiteFadeScreen.FadeOut( );

				if ( m_playerchar.Dead )
					GameScreenManager.AddGameScreen( new GameOverScreen( Level, false ), whiteFadeScreen, GameScreenManager.AddGameScreenData.PositioningOptions.BelowRef );
				else
					GameScreenManager.AddGameScreen( ( (LD27Game)Game ).ChooseNextGame( this, Level + 1 ), whiteFadeScreen, GameScreenManager.AddGameScreenData.PositioningOptions.BelowRef );

				this.KillScreen = true;
			}

			base.Update( dt );
		}

		override public void Render( float dt, GraphicsDevice gd, SpriteBatch sprites )
		{
			sprites.Begin( SpriteSortMode.Deferred, BlendState.NonPremultiplied, null, null, null, null, m_cam.GetWorldMatrix( ) );

			terrain.Render( sprites, m_playerchar );
			m_playerchar.Render( sprites );

			sprites.End( );
			border.Render( gd, sprites );

			sprites.Begin( );

			InputHandler input = Player.Get.GetInput( this );

			if ( input != null && !PlayedYet )
			{
				string str = "";

				if ( input.FindDevice( GamePadInputDevice.DeviceTypeId, -1 ) != null )
				{
					str = "Fire Rocket: A";
				}
				else
				{
					str = "Fire Rocket: W / Space / Up Arrow";
				}

				sprites.DrawString( levelInfoFont, str, new Vector2( Game.GraphicsDevice.PresentationParameters.BackBufferWidth * 0.5f, Game.GraphicsDevice.PresentationParameters.BackBufferHeight * 0.9f ),
					Color.Black, 0.0f, levelInfoFont.MeasureString( str ) * 0.5f, 1.0f, SpriteEffects.None, 1.0f );
			}

			sprites.End( );

			base.Render( dt, gd, sprites );
		}

		override public void OnRemoved( )
		{
			PlayedYet = true;

#if SILVERLIGHT
			rocketSfxInstance.Stop(  );
#else
			rocketSfxInstance.Stop( true );
#endif

#if SILVERLIGHT
			whiteNoiseSfxInstance.Stop(  );
#else
			whiteNoiseSfxInstance.Stop( true );
#endif
			base.OnRemoved( );
		}
	}
}